<template>
  <div class="image-generation">
    <el-card class="main-card">
      <template #header>
        <div class="card-header">
          <span class="header-title">🎨 AI绘图工具</span>
          <span class="header-subtitle">基于 Nano-banana 图像生成</span>
        </div>
      </template>

      <div class="generation-container">
        <!-- 左侧：参数设置 -->
        <div class="params-panel">
          <el-form :model="form" label-width="100px" label-position="top">
            <el-form-item label="模型选择" required>
              <el-select v-model="form.model" placeholder="请选择模型" style="width: 100%">
                <el-option label="nano-banana（推荐）" value="nano-banana" />
                <el-option label="nano-banana-hd（高清4K）" value="nano-banana-hd" />
              </el-select>
            </el-form-item>

            <el-form-item label="图片描述（Prompt）" required>
              <el-input
                v-model="form.prompt"
                type="textarea"
                :rows="6"
                placeholder="请详细描述你想要生成的图片，例如：一只可爱的橘猫坐在窗台上，阳光透过窗户洒在它身上，背景是温馨的客厅..."
                maxlength="1000"
                show-word-limit
              />
            </el-form-item>

            <el-form-item label="图片比例" required>
              <el-radio-group v-model="form.aspectRatio" :disabled="hasReferenceImage">
                <el-radio label="1:1">1:1（正方形）</el-radio>
                <el-radio label="4:3">4:3（横屏）</el-radio>
                <el-radio label="3:4">3:4（竖屏）</el-radio>
                <el-radio label="16:9">16:9（宽屏）</el-radio>
                <el-radio label="9:16">9:16（竖屏宽）</el-radio>
                <el-radio label="2:3">2:3（竖屏）</el-radio>
                <el-radio label="3:2">3:2（横屏）</el-radio>
                <el-radio label="1:2">1:2（超竖屏）</el-radio>
              </el-radio-group>
              <div v-if="hasReferenceImage" class="tip-text">
                <el-icon><InfoFilled /></el-icon>
                图生图模式下不支持设置图片比例
              </div>
            </el-form-item>

            <el-form-item label="返回格式">
              <el-radio-group v-model="form.responseFormat">
                <el-radio label="url">URL链接</el-radio>
                <el-radio label="b64_json">Base64编码</el-radio>
              </el-radio-group>
            </el-form-item>

            <el-form-item label="参考图片（图生图，可选）">
              <el-upload
                class="image-uploader"
                :auto-upload="false"
                :show-file-list="false"
                :on-change="handleImageChange"
                accept="image/*"
              >
                <el-button type="primary" :icon="Upload">上传参考图片</el-button>
              </el-upload>
              <div v-if="form.image && form.image.length > 0" class="reference-images">
                <div v-for="(img, index) in form.image" :key="index" class="reference-image-item">
                  <img :src="img.startsWith('data:') ? img : img" alt="参考图片" />
                  <el-button
                    type="danger"
                    size="small"
                    :icon="Delete"
                    circle
                    @click="removeReferenceImage(index)"
                  />
                </div>
              </div>
            </el-form-item>

            <el-form-item>
              <el-button
                type="primary"
                size="large"
                :loading="generating"
                :disabled="!canGenerate"
                @click="handleGenerate"
                style="width: 100%"
              >
                <el-icon v-if="!generating"><MagicStick /></el-icon>
                {{ generating ? '生成中...' : '生成图片' }}
              </el-button>
            </el-form-item>
          </el-form>
        </div>

        <!-- 右侧：结果展示 -->
        <div class="result-panel">
          <div v-if="!generatedImages.length && !generating" class="empty-state">
            <el-icon :size="80"><Picture /></el-icon>
            <p>生成的图片将在这里显示</p>
          </div>

          <div v-if="generating" class="generating-state">
            <el-progress :percentage="progress" :show-text="false" />
            <p>正在生成图片，请稍候...</p>
          </div>

          <div v-if="generatedImages.length > 0" class="images-grid">
            <div
              v-for="(image, index) in generatedImages"
              :key="index"
              class="image-item"
            >
              <div class="image-wrapper">
                <img
                  :src="image.url || `data:image/png;base64,${image.b64Json}`"
                  :alt="`生成的图片 ${index + 1}`"
                  @load="onImageLoad"
                />
                <div class="image-actions">
                  <el-button
                    type="primary"
                    size="small"
                    :icon="Download"
                    @click="downloadImage(image, index)"
                  >
                    下载
                  </el-button>
                  <el-button
                    type="success"
                    size="small"
                    :icon="CopyDocument"
                    @click="copyImageUrl(image)"
                  >
                    复制链接
                  </el-button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </el-card>
  </div>
</template>

<script setup>
import { ref, reactive, computed } from 'vue'
import { ElMessage } from 'element-plus'
import {
  MagicStick,
  Upload,
  Delete,
  Download,
  CopyDocument,
  Picture,
  InfoFilled
} from '@element-plus/icons-vue'
import { imageApi } from '@/services/imageApi'

defineOptions({
  name: 'ImageGeneration'
})

// 表单数据
const form = reactive({
  model: 'nano-banana',
  prompt: '',
  aspectRatio: '16:9',
  responseFormat: 'url',
  image: []
})

const generating = ref(false)
const progress = ref(0)
const generatedImages = ref([])

// 计算属性
const hasReferenceImage = computed(() => {
  return form.image && form.image.length > 0
})

const canGenerate = computed(() => {
  return form.prompt.trim().length > 0 && form.model && form.aspectRatio
})

// 处理图片上传
const handleImageChange = (file) => {
  const reader = new FileReader()
  reader.onload = (e) => {
    const base64 = e.target.result
    if (!form.image) {
      form.image = []
    }
    form.image.push(base64)
  }
  reader.readAsDataURL(file.raw)
}

// 移除参考图片
const removeReferenceImage = (index) => {
  form.image.splice(index, 1)
}

// 生成图片
const handleGenerate = async () => {
  if (!canGenerate.value) {
    ElMessage.warning('请填写图片描述')
    return
  }

  generating.value = true
  progress.value = 0
  generatedImages.value = []

  // 模拟进度
  const progressInterval = setInterval(() => {
    if (progress.value < 90) {
      progress.value += Math.random() * 15
    }
  }, 300)

  try {
    const params = {
      model: form.model,
      prompt: form.prompt,
      aspectRatio: form.aspectRatio,
      responseFormat: form.responseFormat
    }

    if (form.image && form.image.length > 0) {
      params.image = form.image
    }

    const response = await imageApi.generateImage(params)

    clearInterval(progressInterval)
    progress.value = 100

    if (response && response.data) {
      generatedImages.value = response.data
      ElMessage.success('图片生成成功！')
    } else {
      throw new Error('未返回图片数据')
    }
  } catch (error) {
    clearInterval(progressInterval)
    progress.value = 0
    console.error('生成图片失败:', error)
    
    // 处理超时错误
    if (error.code === 'ECONNABORTED' || error.message?.includes('timeout')) {
      ElMessage.error('请求超时，图像生成可能需要更长时间，请稍后重试或检查网络连接')
    } else {
      ElMessage.error('生成失败：' + (error.message || '未知错误'))
    }
  } finally {
    generating.value = false
    setTimeout(() => {
      progress.value = 0
    }, 1000)
  }
}

// 图片加载完成
const onImageLoad = () => {
  // 可以在这里添加图片加载完成的处理
}

// 下载图片
const downloadImage = async (image, index) => {
  try {
    const imageUrl = image.url || `data:image/png;base64,${image.b64Json}`
    
    if (image.url) {
      // 如果是URL，需要先获取图片
      const response = await fetch(image.url)
      const blob = await response.blob()
      const url = window.URL.createObjectURL(blob)
      const link = document.createElement('a')
      link.href = url
      link.download = `generated-image-${Date.now()}-${index + 1}.png`
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      window.URL.revokeObjectURL(url)
    } else {
      // Base64直接下载
      const link = document.createElement('a')
      link.href = imageUrl
      link.download = `generated-image-${Date.now()}-${index + 1}.png`
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
    }

    ElMessage.success('图片下载成功')
  } catch (error) {
    console.error('下载图片失败:', error)
    ElMessage.error('下载失败')
  }
}

// 复制图片链接
const copyImageUrl = async (image) => {
  try {
    const url = image.url || `data:image/png;base64,${image.b64Json}`
    await navigator.clipboard.writeText(url)
    ElMessage.success('链接已复制到剪贴板')
  } catch (error) {
    console.error('复制失败:', error)
    ElMessage.error('复制失败')
  }
}
</script>

<style scoped>
.image-generation {
  padding: 20px;
  max-width: 1400px;
  margin: 0 auto;
}

.main-card {
  min-height: 600px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-title {
  font-size: 20px;
  font-weight: bold;
  color: #2c3e50;
}

.header-subtitle {
  font-size: 14px;
  color: #909399;
}

.generation-container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  margin-top: 20px;
}

.params-panel {
  padding-right: 20px;
  border-right: 1px solid #e4e7ed;
}

.result-panel {
  min-height: 500px;
}

.empty-state,
.generating-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #909399;
}

.empty-state p,
.generating-state p {
  margin-top: 16px;
  font-size: 14px;
}

.generating-state {
  padding: 40px;
}

.generating-state .el-progress {
  width: 300px;
  margin-bottom: 16px;
}

.images-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}

.image-item {
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  overflow: hidden;
  background: #fff;
}

.image-wrapper {
  position: relative;
  width: 100%;
}

.image-wrapper img {
  width: 100%;
  height: auto;
  display: block;
}

.image-actions {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.6);
  padding: 10px;
  display: flex;
  gap: 8px;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.3s;
}

.image-wrapper:hover .image-actions {
  opacity: 1;
}

.image-actions .el-button {
  color: #fff;
}

.tip-text {
  margin-top: 8px;
  font-size: 12px;
  color: #909399;
  display: flex;
  align-items: center;
  gap: 4px;
}

.reference-images {
  margin-top: 12px;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.reference-image-item {
  position: relative;
  width: 120px;
  height: 120px;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  overflow: hidden;
}

.reference-image-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.reference-image-item .el-button {
  position: absolute;
  top: 4px;
  right: 4px;
}

@media (max-width: 1024px) {
  .generation-container {
    grid-template-columns: 1fr;
  }

  .params-panel {
    padding-right: 0;
    border-right: none;
    border-bottom: 1px solid #e4e7ed;
    padding-bottom: 24px;
    margin-bottom: 24px;
  }
}
</style>

